fix(example-crm): make formula fields compute + allow historical closed deals; bump objectui#1927
Merged
os-zhuang merged 1 commit intoJun 15, 2026
Conversation
…ed deals; bump objectui
Release-prep browser test of example-crm surfaced three "passes build,
silently wrong at runtime" defects:
- Formula fields (`full_name`, `is_closed`, `expected_revenue`) referenced
bare field identifiers (`amount`, `status`, `first_name`). Formula scope
exposes only `{record, previous, input, os}` with no field flattening, so
bare names resolve to nothing and every formula evaluated to null. Rewrite
to `record.<field>`.
- `expected_revenue` additionally divided by the int literal `100`. cel-js
has no `double × int` arithmetic overload, so `<number field> / 100` faults
and the formula returns null. Use the float literal `100.0` (both operands
`double`). The systemic guardrail for this footgun is tracked separately.
- `opp_close_date_not_past` validation fired on every insert, rejecting the
legitimate `closed_won`/`closed_lost` seed rows that carry historical close
dates (5 of 9 wins were dropped, breaking the pipeline dashboard's
"Won This Quarter" KPIs). Scope the rule to open stages only.
Also bumps `.objectui-sha` 26da1a2a3731 → ac2de168d487 and rebuilds the
bundled @objectstack/console dist for the release.
Verified live: opportunities seed 4 → 12; expected_revenue computes
(84000, 180000, …); full_name / is_closed populate.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Author
|
Systemic guardrail tracked in #1928 (build-time lint and/or engine int→double promotion). |
os-zhuang
deleted the
fix/example-crm-formula-validation-and-objectui-bump
branch
June 15, 2026 17:59
This was referenced Jun 15, 2026
os-zhuang
added a commit
that referenced
this pull request
Jun 16, 2026
… (#1931) A Field.formula and an object validation predicate evaluate against the `record` namespace only (no field flattening), so a bare top-level identifier (`amount`, `status`) resolves to nothing and the expression silently evaluates to null / never fires — the silent-at-runtime class behind #1927. `validateExpression` gains an evaluation `scope`; for `scope: 'record'` it reports a bare reference with the corrective `record.<field>` form. It acts only on cel-js's `Unknown variable` fault, so it cannot false-positive on arithmetic/comparison/null-guard overloads. Flow & automation conditions keep the default `scope: 'flattened'` — the record's fields are spread to top-level there alongside flow variables, so bare refs are correct and NOT flagged. `objectstack compile` wires record scope for field formulas + validation predicates; flow conditions stay flattened. Also fixes three latent bare-ref bugs surfaced by the new check: - crm_lead validation `lead_score_range` (rule silently never fired) - showcase field_zoo `f_formula`, showcase project `budget_remaining` (null) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Release-prep browser test of
example-crm(9.5.x) surfaced three "passes build, silently wrong at runtime" defects — the failure class this project's AI-authoring guardrails target. All three are in the flagship demo app.Fixes
full_name,is_closed,expected_revenueall rendered emptyamount,status,first_name). Formula scope is{record, previous, input, os}with no field flattening, so bare names resolve to nothing →nullrecord.<field>expected_revenuestillnullafter #1… / 100— cel-js has nodouble × intarithmetic overload, so<number field> / 100faults and the formula returnsnull/ 100.0(both operandsdouble)opp_close_date_not_pastvalidation fired on every insert, rejectingclosed_won/closed_lostseed rows that legitimately carry historical close dates (5 of 9 wins dropped)Also bumps
.objectui-sha26da1a2a3731 → ac2de168d487and rebuilds the bundled@objectstack/consoledist for the release.Verification (live dev server + API)
closed_won/closed_lostnow persist)expected_revenuecomputes: 84000, 180000, 16000, 21000, … (=amount × probability / 100)full_name→ "Ada Lovelace",is_closed→ correct booleanpnpm build→ 75/75 tasks pass;example-crmbuilds clean (ADR-0032 expression validation green)Follow-up (deferred)
The cel-js
double × intarithmetic gap is systemic — any AI-authored formula likeprice * 2,total - fee,amount / 100silently returnsnull; only float literals work, and cel-js rejects registering operator overloads.validate-expressions.ts(ADR-0032) catches neither this nor the bare-identifier case. Tracking issue to follow for a build-time lint and/or engine-level int→double promotion.🤖 Generated with Claude Code